package org.dakuo.sgfyModel;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.ArrayList; //import java.util.Timer;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;

public class SgfyVillage {
	private String id;
	private String name;
	private int mainVillage;
	private int locationX;
	private int locationY;
	private String state;
	private SgfyResourceGroup resG;
	private ArrayList<SgfyConstruction> conL;
	private ArrayList<SgfyConstruction> workingConL;
	
	ArrayList<SgfyAutoMissionCons> missionConsList;

	// Timer t;

	public SgfyVillage() {
		setId("0");
		setName("城市");
		setLocationX(0);
		setLocationY(0);
		setState("州");
		setMainVillage(0);
		setWorkingConL(new ArrayList<SgfyConstruction>());
		setResG(new SgfyResourceGroup());
		setConL(new ArrayList<SgfyConstruction>());
		missionConsList = new ArrayList<SgfyAutoMissionCons>();
	}

	public SgfyVillage(String id, String name, String locationX,
			String locationY, String state, String mainVillage) {
		setId(id);
		setName(name);
		setLocationX(Integer.parseInt(locationX));
		setLocationY(Integer.parseInt(locationY));
		setState(state);
		setMainVillage(Integer.parseInt(mainVillage));
		setWorkingConL(new ArrayList<SgfyConstruction>());
		setResG(new SgfyResourceGroup());
		setConL(new ArrayList<SgfyConstruction>());
		missionConsList = new ArrayList<SgfyAutoMissionCons>();
	}

	public void addCons(SgfyConstruction con) {
		this.getConL().add(con);
	}

	public double updateCons(String name, String level,List<Cookie> cookieList, String hostURI) {
		SgfyConstruction con = new SgfyConstruction(name, level);
		for (SgfyConstruction cTemp : this.conL){
			if (cTemp.equals(con)) {
				cTemp.getInfo(this.id,cookieList,hostURI);
				if (canBeUpdate(cTemp)) {
					resG.consumeResource(cTemp.getResNeed());
					cTemp.setInWorkStatus(true);
					workingConL.add(cTemp);
					if( cTemp.update(this.id,cookieList,hostURI))
					return cTemp.updateDuration;
				}
			}
		}
		System.out.println("fail to update");
		return -1;
	}

	private boolean canBeUpdate(SgfyConstruction con) {

		if (con.isInWorkStatus())
			return false;
		if (this.workingConL.size() >= 2)
			return false;
		float[] resNow = resG.getNow();
		float[] resNeed = con.getResNeed();
		for (int i = 0; i < 5; i++) {
			if (resNow[i] < resNeed[i])
				return false;
		}
		return true;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getId() {
		return id;
	}

	public void setMainVillage(int mainVillage) {
		this.mainVillage = mainVillage;
	}
	public int getMainVillage(){
		return this.mainVillage;
	}

	public boolean isMainVillage() {
		if(this.mainVillage==1)
			return true;
		return false;
	}

	public void setLocationX(int locationX) {
		this.locationX = locationX;
	}

	public int getLocationX() {
		return locationX;
	}

	public void setLocationY(int locationY) {
		this.locationY = locationY;
	}

	public int getLocationY() {
		return locationY;
	}

	public void setState(String state) {
		this.state = state;
	}
	
	public String getState() {
		return state;
	}
	
	public void setLocationX(String locationX) {
		setLocationX(Integer.parseInt(locationX));
	}
	public void setLocationY(String locationY) {
		setLocationY(Integer.parseInt(locationY));
	}
	public void setResG(SgfyResourceGroup resG) {
		this.resG = resG;
	}

	public SgfyResourceGroup getResG() {
		return resG;
	}

	public void setConL(ArrayList<SgfyConstruction> conL) {
		this.conL = conL;
	}

	public ArrayList<SgfyConstruction> getConL() {
		return conL;
	}

	public void setWorkingConL(ArrayList<SgfyConstruction> workingConL) {
		this.workingConL = workingConL;
	}

	public ArrayList<SgfyConstruction> getWorkingConL() {
		return workingConL;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public String toString() {
		return "Village_" + this.id + "_" + this.name + "_(" + this.locationX
				+ "," + this.locationY + ")_" +state+"_"+mainVillage+ resG + conL
				+ workingConL;

	}


	public List<Cookie> getVillageInfo(List<Cookie> cookieList,String hostURI) {
		try {
			DefaultHttpClient httpClient = new DefaultHttpClient();

			Iterator<Cookie> ci = cookieList.iterator();
			while (ci.hasNext())
				httpClient.getCookieStore().addCookie(ci.next());

			/**
			 * Get OutCity info
			 */
			HttpGet httpGet = new HttpGet(hostURI);
			httpGet
					.setHeader(
							"User-Agent",
							"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)");
			httpGet
					.addHeader("Accept",
							"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
			httpGet.addHeader("Accept-Language", "en-us,en;q=0.5");
			httpGet.addHeader("Accept-Charset",
					"ISO-8859-1,utf-8;q=0.7,*;q=0.7");
			httpGet.addHeader("Content-Type",
					"application/x-www-form-urlencoded");

			HttpResponse response = httpClient.execute(httpGet);
			HttpEntity entity = response.getEntity();

			if (entity != null) {
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(entity.getContent()));
				try {

					Pattern p = Pattern
							.compile(
									"sgtitle=\"(\\W+)(\\s+)Lv.(\\d+)\".*(MM_xmlLoad\\(')(\\w+\\.\\w+\\&\\w+=\\d+)(.*/>$)",
									Pattern.DOTALL);
					Matcher m;
					String line = reader.readLine();
					while (line != null) {
						m = p.matcher(line);
						if (m.find()) {
							this.getConL().add(
									new SgfyConstruction(m.group(1),
											m.group(3), m.group(5)));
						    
						}  else {

						}
						line = reader.readLine();
					}

				} catch (IOException ex) {

					throw ex;

				} catch (RuntimeException ex) {

					httpGet.abort();
					throw ex;

				} finally {

					reader.close();

				}
			}

			String inCityUrl = hostURI
					+ "index.php?act=build.status&villageid="
					+ this.id + "&rand=" + "775836";

			/**
			 * Get InCity Info
			 */
			httpGet.setURI(new URI(inCityUrl));
			response = httpClient.execute(httpGet);
			entity = response.getEntity();
			if (entity != null) {
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(entity.getContent()));
				try {

					Pattern p = Pattern
							.compile(
									"sgtitle=\"\\s+(\\W+)(\\s+)Lv.(\\d+)(\\s+)\".*(MM_xmlLoad\\(')(\\w+\\.\\w+\\&\\w+=\\d+)(.*/>$)",
									Pattern.DOTALL);
					Pattern pEmpty = Pattern
							.compile(
									"sgtitle=\"(\\s)+(空地)(\\s+).*(MM_xmlLoad\\(')(\\w+\\.\\w+\\&\\w+=\\d+)(.*/>$)",
									Pattern.DOTALL);
					Pattern pResource = Pattern
							.compile("<reso\\sid=\"(\\w+)\"\\snow=\"(\\d+(.\\d+)*)\"\\smax=\"(\\d+(.\\d+)*)\"\\sspeed=\"(\\d+(.\\d+)*)\"\\sincrease=\"(\\d+(.\\d+)*)\"\\s(buff=\"(\\d+(.\\d+)*)\")*");

					Matcher m;
					Matcher mEmpty;
					Matcher mResource;

					String line = reader.readLine();
					while (line != null) {
						m = p.matcher(line);
						mEmpty = pEmpty.matcher(line);
						mResource = pResource.matcher(line);

						if (m.find()) {
							this.getConL().add(
									new SgfyConstruction(m.group(1).substring(0, m.group(1).length()-1),
											m.group(3), m.group(6)));
						} else if (mEmpty.find()) {
							this.getConL().add(
									new SgfyConstruction(mEmpty.group(2), "1",
											mEmpty.group(5)));
						} else if (mResource.find()) {

							SgfyResource resTemp = new SgfyResource(mResource
									.group(1), mResource.group(2), mResource
									.group(4), mResource.group(6), mResource
									.group(8), mResource.group(11));
							this.getResG().addResource(resTemp);
						} 

						line = reader.readLine();
					}

				} catch (IOException ex) {

					throw ex;

				} catch (RuntimeException ex) {

					httpGet.abort();
					throw ex;

				} finally {

					reader.close();

				}
			}

			cookieList = httpClient.getCookieStore().getCookies();
			
			httpClient.getConnectionManager().shutdown();
			
			return cookieList;

		} catch (Exception e) {

			System.out.println(e.getStackTrace());
			return null;
		}
	}

	public void addMissionCons(SgfyAutoMissionCons mc) {
		this.missionConsList.add(mc);
	}
	
	/**
	 * 返回建造时间，为之后的thread sleep用
	 */
	public double doMissionCons(){
		if(this.missionConsList!=null)
		{
			String conName = missionConsList.get(0).getConsName();
			String conLevel = missionConsList.get(0).getConsLevel();
			List<Cookie> cookieL = missionConsList.get(0).getCookieList();
			String hostURI = missionConsList.get(0).getHostURI();
			double duration = this.updateCons(conName, conLevel, cookieL, hostURI);
			if(duration != -1){
				this.missionConsList.remove(0);
			return duration;
			}
			else{
				System.out.println("Can not update now");
				return -1;
				}
		}
		return -1;
		
	}
	
	public static void main(String[] arg) {
		SgfyVillage v = new SgfyVillage();
		System.out.println(v);
	}

}
